[PYTHON] J'ai écrit une animation que le système linéaire rétrécit avec du code sale mortel

Que fais tu

Mon junior à l'université a dit que je ne pouvais pas obtenir l'image de la contraction du système linéaire, alors j'ai décidé de faire une animation qui fusionne les vecteurs propres du système linéaire bidimensionnel. L'équation à résoudre est extrêmement simple et a la forme suivante.

\frac{d}{dt}\Bigl(\begin{matrix}
x\\
y
\end{matrix} \Bigl)=
\Bigl(\begin{matrix}
-1 & -1\\
0 & -1-\epsilon
\end{matrix}\Bigl)\Bigl(\begin{matrix}x\\
y\end{matrix}\Bigl)

La contraction est résolue à l'avance en mettant la perturbation $ \ epsilon $ uniquement dans la composante $ (2,2) $ de la matrice $ 2 \ times 2 $. Ensuite, l'instruction for est tournée pour changer progressivement $ \ epsilon $, et chaque étape est intégrée avec scipy odeint à partir de plusieurs conditions initiales. Dans l'exemple ci-dessous, les nœuds stables sont rétractés. Si vous tournez un peu plus l'instruction for, vous pouvez voir que l'origine change pour la selle, et selon la façon dont vous insérez la perturbation, vous devriez également voir la transition entre le nœud et la spirale.

Code réellement écrit

Puisqu'il s'agit d'un code anti-intelligent, je me demandais s'il fallait le publier pendant une demi-journée, mais je le publierai dans l'espoir que quelqu'un fera des commentaires significatifs. Dans l'instruction for, le paramètre de perturbation $ e (= \ epsilon) $ est calculé pour chaque étape en fonction du nombre d'étapes, et l'équation différentielle est résolue sur cette base.

Linear_degenerate.ipynb



%matplotlib nbagg
import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import odeint
from numpy import sin, cos, pi
import matplotlib.animation as animation
# degeneration of linear system
def func(v, t, e):
    return [ -v[0] - v[1], -(1+e)*v[1] ] #  2-D linear system

#def func(v,t):
#    return [ -v[1] -0.5*v[0]*(v[0]**2+v[1]**2), v[0] -0.5*v[1]*(v[0]**2 + v[1]**2)]

# time length and unit step    
dt = 0.1
T = np.arange(0.0, 20, dt)
v0 = [[17,7], [17,17], [7,17], [-17,-7], [-17,-17], [-7,-17],[-7,17], [7,-17]]

# make animation
fig = plt.figure()

ims = []

for k in range(200):
    e = (150-k)/50
    #each initial state
    space = []
    for v, color in zip(v0, 'rbgrbgkk'):
        u = odeint(func, v, T, args=(e,))
        space += plt.plot(u[:,0], u[:,1], color)

    ims.append(space)
    
    
    '''u0 = odeint(func, v0[0], T, args=(e,))
    space0 = plt.plot(u0[:,0], u0[:,1], 'r')
    u1 = odeint(func, v0[1], T, args=(e,))
    space1 = plt.plot(u1[:,0], u1[:,1], 'b')
    u2 = odeint(func, v0[2], T, args=(e,))
    space2 = plt.plot(u2[:,0], u2[:,1], 'g')
    u3 = odeint(func, v0[3], T, args=(e,))
    space3 = plt.plot(u3[:,0], u3[:,1], 'r')
    u4 = odeint(func, v0[4], T, args=(e,))
    space4 = plt.plot(u4[:,0], u4[:,1], 'b')
    u5 = odeint(func, v0[5], T, args=(e,))
    space5 = plt.plot(u5[:,0], u5[:,1], 'g')
    u6 = odeint(func, v0[6], T, args=(e,))
    space6 = plt.plot(u6[:,0], u6[:,1], 'k')
    u7 = odeint(func, v0[7], T, args=(e,))
    space7 = plt.plot(u7[:,0], u7[:,1], 'k')

    ims.append(space0+space1+space2+space3+space4+space5+space6+space7)
    '''
plt.xlim(-17 ,17) 
plt.ylim(-17 ,17)
plt.xlabel('x')
plt.ylabel('y')
plt.grid()
ani = animation.ArtistAnimation(fig, ims, interval=27, blit=True, repeat=True)

plt.show()

Exemple d'exécution

Lin_Deg.gif

Vous pouvez voir que la direction unique, qui était indépendante du premier ordre de $ x $, se réduit progressivement en $ x $.

problème

Le code ci-dessus est plein de problèmes ~~ 1: La même opération est effectuée plusieurs fois dans l'instruction for ~~ ~~ 2: Je voulais l'automatiser, mais je ne pensais pas à la façon de changer la couleur en fonction de la valeur initiale ~~ 3: J'ai oublié l'intrigue dans la direction spécifique même si je regarde la contraction Et ainsi de suite (alors vous pouvez le réparer vous-même).

Je ferai quelque chose plus tard si je peux écrire un code plus intelligent ~~. Grâce à la gentille personne qui m'a appris ~~, les problèmes 1 et 2 ont été résolus. Merci encore. En ce qui concerne la partie du problème qui a été résolue, j'ai décidé de laisser le code sale que j'avais écrit dans le commentaire. J'ai pensé que ce serait bien si je pouvais imaginer un peu plus l'emplacement des conditions initiales, mais comme l'emplacement facile à voir diffère selon le système, je me demande si je dois le récupérer à la main après tout.

Recommended Posts

J'ai écrit une animation que le système linéaire rétrécit avec du code sale mortel
[Python] J'ai écrit un code simple qui génère automatiquement AA (Ascii Art)
J'ai écrit un bot Slack qui notifie les informations de retard avec AWS Lambda
Un mémo que j'ai écrit un tri rapide en Python
J'ai essayé de créer un environnement avec WSL + Ubuntu + VS Code dans un environnement Windows
Un mémo que j'ai touché au magasin de données avec python
J'ai écrit un code qui dépasse le taux de récupération de 100% dans la prédiction des courses de chevaux en utilisant LightGBM (partie 2)
Une histoire qui a trébuché lorsque j'ai créé un bot de chat avec Transformer
J'ai écrit le code pour la génération de phrases japonaises avec DeZero
Un code de tri de chaîne qui utilise un algorithme qui génère une permutation.
J'ai écrit rapidement un programme pour étudier la DI avec Python ①
J'ai écrit un programme de démonstration pour la transformation linéaire d'une matrice
J'ai fait une animation qui renvoie la pierre d'Othello avec POV-Ray
J'ai fait une minuterie pomodoro dure qui fonctionne avec CUI
J'ai créé un plug-in qui peut faire "Daruma-san tombé" avec Minecraft
J'ai écrit un script qui divise l'image en deux