[PYTHON] I wrote an animation that degenerates a linear system with deadly dirty code

What you are doing

A junior at the university said that the image of the degeneracy of the linear system did not come up, so I decided to make an animation in which the eigenvectors of the two-dimensional linear system were fused. The equation to be solved is extremely simple and has the following form.

\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)

The degeneracy is solved in advance by putting the perturbation $ \ epsilon $ only in the $ (2,2) $ component of the $ 2 \ times 2 $ matrix. Then, the for statement is rotated to gradually change $ \ epsilon $, and each step is integrated with scipy odeint from multiple initial conditions. In the sample below, the stable node is degenerated. If you turn the for statement a little more, you can see that the origin changes to the saddle, and depending on how you put in the perturbation, you should also see the transition between the node and the spiral.

Code actually written

Since it is an anti-intellectual code, I was worried about whether to publish it for half a day, but I will publish it in the hope that someone will make a meaningful comment. In the for statement, the perturbation parameter $ e (= \ epsilon) $ is calculated for each step according to the number of steps, and the differential equation is solved based on that.

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()

Execution example

Lin_Deg.gif

You can see that the unique direction, which was first-order independent of $ x $, gradually collapses into $ x $.

problem

The code above is full of problems, ~~ 1: The same operation is performed many times in the for statement ~~ ~~ 2: I wanted to automate it, but I wasn't thinking about how to change the color according to the initial value ~~ 3: I have forgotten the plot in the proper direction even though I am watching the degeneracy And so on (then you can fix it yourself).

I'll do something later if I can write smarter code ~~. Thanks to the kind person who taught me ~~, problems 1 and 2 have been solved. Thank you again. As for the part of the problem that was solved, I decided to comment out the dirty code I wrote. I thought it would be nice if I could devise a place for the initial conditions a little more, but since the places that are easy to see differ depending on the system, I wonder if I have to get it by hand after all.

Recommended Posts

I wrote an animation that degenerates a linear system with deadly dirty code
[Python] I wrote a simple code that automatically generates AA (ASCII art)
I wrote a Slack bot that notifies delay information with AWS Lambda
A memo that I wrote a quicksort in Python
I made a QR code image with CuteR
I tried to build an environment with WSL + Ubuntu + VS Code in a Windows environment
A memo that I touched the Datastore with python
[Python, ObsPy] I wrote a beach ball with Matplotlib + ObsPy
I wrote a code that exceeds 100% recovery rate in horse racing prediction using LightGBM (Part 2)
A story that stumbled when I made a chatbot with Transformer
I wrote the code for Japanese sentence generation with DeZero
I made a LINE BOT that returns parrots with Go
A string permutation code that uses an algorithm that generates permutations.
I wrote a program quickly to study DI with Python ①
I wrote a demo program for linear transformation of a matrix
I made an animation to return Othello stones with POV-Ray
I made a rigid Pomodoro timer that works with CUI
I made a plug-in that can "Daruma-san fell" with Minecraft
I wrote a script that splits the image in two